package me.twoday.library.mine.common.network;

import java.util.ArrayList;

/**
 * 커넥션을 관리하는 매니저 클래스
 * 
 * @author 박우람
 * @since 2011.02.12
 */
public class ConnectionManager
{
	public static final int MAX_CONNECTIONS = 10;
	 
    private ArrayList<Runnable> active = new ArrayList<Runnable>();
    private ArrayList<Runnable> queue = new ArrayList<Runnable>();

    private static ConnectionManager instance;
    private static Object mLock = new Object();

    /**
     * 커넥션 매니져를 반환하는 싱글턴 방식의 메서드
     * 
     * @return 커넥션 매니져 객체
     */
    public static ConnectionManager getInstance()
    {
         if (instance == null)
         {
              instance = new ConnectionManager();
         }
         
         return instance;
    }

    /**
     * 새로 실행할 쓰레드를 추가
     * 
     * @param runnable 실행할 쓰레드
     */
    public void push(Runnable runnable)
    {
    	synchronized(mLock)
		{
    		queue.add(runnable);
    		
    		if (active.size() < MAX_CONNECTIONS)
    		{
    			startNext();
    		}
    		// 열러진 커넥션수가 너무 클 경우 현재 실행중인 커넥션 초기화
    		else
    		{
    			active.clear();
    			startNext();
    		}
		}
    }

    /**
     * 다음의 실행할 메서드를 수행
     */
    private void startNext()
    {
    	synchronized(mLock)
		{
	         if (!queue.isEmpty())
	         {
	              Runnable next = (Runnable) queue.get(0);
	              queue.remove(0);
	              active.add(next);
	
	              Thread thread = new Thread(next);
	              thread.start();
	         }
		}
    }

    /**
     * 쓰레드 수행 종료시 기존의 큐를 삭제하고 다음을 실행
     * 
     * @param runnable 수행할 쓰레드
     */
    public void didComplete(Runnable runnable)
    {
    	synchronized(mLock)
		{
    		active.remove(runnable);
    		startNext();
		}
    }
}
